package com.systemCapacity.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.systemCapacity.common.dto.*;
import com.systemCapacity.entity.BattleActivity;
import com.systemCapacity.entity.BattlePlan;
import com.systemCapacity.entity.BattleTask;
import com.systemCapacity.entity.Enum.BattleActivityType;
import com.systemCapacity.entity.Enum.TaskType;
import com.systemCapacity.mapper.BattleTaskMapper;
import com.systemCapacity.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BattleTaskServiceImpl extends ServiceImpl<BattleTaskMapper, BattleTask> implements BattleTaskService {

    @Autowired
    private BattleTaskMapper battleTaskMapper;

    @Autowired
    private BattlePlanService battlePlanService;

    @Autowired
    private BattleActivityService battleActivityService;

    @Autowired
    private ActivityResourceService activityResourceService;

    @Autowired
    private BattlePlatformService battlePlatformService;

    @Autowired
    private BlueBattlePlatformService blueBattlePlatformService;


    @Override
    public IPage<BattleTask> getTaskPage(int page, int size) {
        Page<BattleTask> taskPage = new Page<>(page, size);
        LambdaQueryWrapper<BattleTask> taskLambdaQueryWrapper = Wrappers.lambdaQuery();
        taskLambdaQueryWrapper.orderByAsc(BattleTask::getTaskId);
        return battleTaskMapper.selectPage(taskPage, taskLambdaQueryWrapper);
    }

    @Override
    public boolean taskExist(String taskId) {
        QueryWrapper<BattleTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("taskId", taskId);
        return getOne(queryWrapper) != null;
    }

    @Override
    public boolean taskNameExist(String taskName) {
        QueryWrapper<BattleTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("taskName", taskName);
        return getOne(queryWrapper) != null;
    }

    @Override
    @Transactional
    public boolean deleteTsk(String taskId) {
        battlePlanService.getPlansByTaskId(taskId).forEach(plan -> battlePlanService.deletePlanNew(plan.getPlanId()));
        //删除蓝方
        blueBattlePlatformService.deletePlatformByTaskId(taskId);
        removeById(taskId);
        return true;
    }

    @Override
    public List<RelatedBattleTaskDto> getRelatedBattleTask(String capacityId) {
        List<RelatedBattleTaskDto> dtos = new ArrayList<>();
        List<String> activityIds = activityResourceService.getRelatedActivities(capacityId);
        if (activityIds.isEmpty()) {
            return dtos;
        }
        List<BattleActivity> activities = battleActivityService.getBaseMapper().selectBatchIds(activityIds);
        Map<String, List<BattleActivity>> planDtoMap = new HashMap<>();
        activities.forEach(activity -> {
            if (planDtoMap.containsKey(activity.getPlanId())) {
                planDtoMap.get(activity.getPlanId()).add(activity);
            } else {
                ArrayList<BattleActivity> battleActivities = new ArrayList<>();
                battleActivities.add(activity);
                planDtoMap.put(activity.getPlanId(), battleActivities);
            }
        });
        List<String> planIds = new ArrayList<>(planDtoMap.keySet());
        List<BattlePlan> plans = battlePlanService.getBaseMapper().selectBatchIds(planIds);
        Map<String, RelatedBattleTaskDto> relatedBattleTaskDtoMap = new HashMap<>();
        plans.forEach(battlePlan -> {
            RelatedBattlePlanDto dto = new RelatedBattlePlanDto();
            dto.setPlanId(battlePlan.getPlanId());
            dto.setPlanName(battlePlan.getPlanName());
            List<BattleActivity> activityList = planDtoMap.get(battlePlan.getPlanId());
            List<BattleActivityType> types = activityList.stream()
                    .map(activity -> BattleActivityType.values()[activity.getActivityType()])
                    .collect(Collectors.toList());
            dto.setActivities(types);
            if (relatedBattleTaskDtoMap.containsKey(battlePlan.getTaskId())) {
                relatedBattleTaskDtoMap.get(battlePlan.getTaskId()).getPlanDtos().add(dto);
            } else {
                RelatedBattleTaskDto taskDto = new RelatedBattleTaskDto();
                taskDto.setTaskId(battlePlan.getTaskId());
                taskDto.setTaskName(getById(battlePlan.getTaskId()).getTaskName());
                ArrayList<RelatedBattlePlanDto> battlePlanDtos = new ArrayList<>();
                battlePlanDtos.add(dto);
                taskDto.setPlanDtos(battlePlanDtos);
                dtos.add(taskDto);
                relatedBattleTaskDtoMap.put(battlePlan.getTaskId(), taskDto);
            }
        });
        return dtos;
    }

    @Override
    @Transactional
    public void saveTask(BattleTaskDto taskDto){
        BattleTask task = new BattleTask();
        task.setTaskName(taskDto.getTaskName());
        task.setTaskId(UUID.randomUUID().toString());
        task.setTaskType(taskDto.getTaskType().getValue());
        task.setCreatedUser(taskDto.getUserName());
        task.setCreatedTime(LocalDateTime.now());
        save(task);
        List<BlueBattlePlatformDto> platformList = taskDto.getBluePlatFormList();
        platformList = platformList.stream().filter(x -> !StringUtils.isEmpty(x.getEquipmentId())).collect(Collectors.toList());
        if (!platformList.isEmpty()) {
            platformList.forEach(x -> x.setTaskId(task.getTaskId()));
            blueBattlePlatformService.savePlatForm(platformList);
        }
    }

    @Override
    @Transactional
    public void editTask(BattleTaskDto taskDto){
        BattleTask task = new BattleTask();
        task.setTaskName(taskDto.getTaskName());
        task.setTaskId(taskDto.getTaskId());
        task.setTaskType(taskDto.getTaskType().getValue());
        task.setCreatedUser(taskDto.getUserName());
        task.setCreatedTime(LocalDateTime.now());

        UpdateWrapper<BattleTask> taskUpdateWrapper = new UpdateWrapper<>();
        taskUpdateWrapper.eq("taskId",taskDto.getTaskId());
        update(task,taskUpdateWrapper);
        blueBattlePlatformService.deletePlatformByTaskId(taskDto.getTaskId());
        List<BlueBattlePlatformDto> platformList = taskDto.getBluePlatFormList();
        if (!platformList.isEmpty()) {
            platformList.forEach(x -> x.setTaskId(taskDto.getTaskId()));
            blueBattlePlatformService.savePlatForm(platformList);
        }
    }

    @Override
    @Transactional
    public BattleTaskDto getTaskDetail(String taskId) {
        QueryWrapper<BattleTask> taskQueryWrapper = new QueryWrapper<>();
        taskQueryWrapper.eq("taskId",taskId);
        BattleTask battleTask = battleTaskMapper.selectOne(taskQueryWrapper);

        BattleTaskDto taskDto = new BattleTaskDto();
        BeanUtils.copyProperties(battleTask,taskDto);
        taskDto.setTaskType(convertTaskType(battleTask.getTaskType()));
        List<BlueBattlePlatformDto> battlePlatformDtoList = blueBattlePlatformService.queryPlatformListByTaskId(taskId);
        taskDto.setBluePlatFormList(battlePlatformDtoList);
        return taskDto;
    }
    private TaskType convertTaskType(Integer type){
        TaskType taskType = null;
        if(type == null){
            return null;
        }
        switch (type){
            case 0 :
                taskType = TaskType.RECONNOITRE;
                break;
            case 1:
                taskType = TaskType.INTERFERENCE;
                break;
            case 2:
                taskType = TaskType.STRIKING;
                break;
            case 3:
                taskType = TaskType.DISCOVERING;
                break;
            case 4:
                taskType = TaskType.TRACKING;
                break;
            case 5:
                taskType = TaskType.POSITIONING;
                break;
            case 6:
                taskType = TaskType.ESTIMATING;
                break;
        }
        return taskType;
    }
}
